package com.wushijia.java8.lambda;

import com.wushijia.model.User;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * description:函数式数据处理
 *
 * @author yang
 * @date 2018/4/29 20:08
 */
public class Chapter3 {

  public static void main(String[] args) {
    //流只能被消费一次
    List<String> list = Arrays.asList("hello", "world");
    Stream<String> stream = list.stream();
    stream.forEach(System.out::println);
    //stream.forEach(System.out::println);第二次消费报错

    //流和集合的区别：遍历数据的方式：流是内部迭代，集合是外部迭代
    List<User> userList = new ArrayList<>();
    userList.add(new User("段誉", "男", 25));
    userList.add(new User("令狐冲", "男", 24));
    userList.add(new User("岳灵珊", "女", 21));
    userList.add(new User("木婉清", "女", 22));

    List<String> nameList = userList.stream().map(User::getName).collect(Collectors.toList());
    System.out.println(nameList);

    //java8引入流的一个重要理由：Streams库的内部迭代可以自动选择一种适合你硬件的数据表示和并行实现
    //中间操作（Filter(谓词)、distinct(筛选)、Sorted(排序)、limit(截取),skip(跳过),其结果仍是一个流）和终端操作（collect,count,for-each,非stream的值，其结果是任何不是流的值，如List,Integer,void等）
    List<String> maxAgeUserList = userList.stream().filter(user -> user.getAge() > 23).map(User::getName).limit(1).collect(Collectors.toList());
    System.out.println(maxAgeUserList);

    //map方法：对流中每一个元素应用函数，它会接受一个函数作为参数
    List<String> allWords = list.stream().map(word -> word.split("")).flatMap(Arrays::stream).distinct().collect(Collectors.toList());
    System.out.println(allWords);

    //[1,2,3,4] --> [1,4,9,16]
    List<Integer> numList = Arrays.asList(1, 2, 3, 4);
    List<Integer> sqList = numList.stream().map(x -> x * x).collect(Collectors.toList());
    System.out.println(sqList);

    //[1,2,3]*[3,4] --> [(1,3),(1,4),(2,3),(2,4),(3,3),(3,4)]
    List<Integer> numList1 = Arrays.asList(1, 2, 3);
    List<Integer> numList2 = Arrays.asList(3, 4);
    List<int[]> fixList = numList1.stream().flatMap(i -> numList2.stream().map(j -> new int[]{i, j})).collect(Collectors.toList());
    System.out.println(fixList);

    //查找和匹配：allmatch(匹配所有),anymatch(至少一个),nonematch(一个都没),findfirst,findany(任意元素)
    boolean b = userList.stream().allMatch(user -> "女".equals(user.getSex()));
    System.out.println(b);

    //Optional:容器类，代表一个值存在或者不存在，isPresent(),ifPresent(Consumer<T> block),T get(),T orElse(T other)
    userList.stream().filter(user -> "男".equals(user.getSex())).findAny().ifPresent(user -> System.out.println(user.getName()));

    //规约：reduce,接受一个初始值，反复结合每个元素，最终返回一个值;无初始值规约返回一个optional对象，因为结果可能是空，流中无数据
    Integer sum = numList.stream().reduce(0, (x, y) -> x + y);
    System.out.println(sum);
    Optional<Integer> max = numList.stream().reduce(Integer::max);
    System.out.println(max.get());

    //集合元素个数
    long count = numList.stream().count();
    long count2 = numList.stream().map(d -> 1).reduce(0, (x, y) -> x + y);//map-reduce模式


  }
}
